home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 9606 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  9.5 KB

  1. Path: news.acadia.net!usenet
  2. From: steven2@salesbook.com (Steve Nutt)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: C++ OO question (long)
  5. Date: Sun, 03 Mar 1996 06:35:38 GMT
  6. Organization: DET
  7. Message-ID: <4hb5tb$91l@post.acadia.net>
  8. References: <4h08uq$mve@madeline.INS.CWRU.Edu>
  9. Reply-To: steven2@salesbook.com
  10. NNTP-Posting-Host: blf7.acadia.net
  11. X-Newsreader: Forte Free Agent 1.0.82
  12.  
  13. bf461@cleveland.Freenet.Edu (Bryan Murphy) wrote:
  14.  
  15.  
  16.  
  17. >/*
  18. >Warning:  This is a long one. 
  19.  
  20. >Ok, I'm fairly new to the C++ programming paradigm.  While I've 
  21. >quite a bit of experience with the C++ syntax, I've only just
  22. >begun to understand the concepts that really go into an OOP 
  23. >program.  
  24.  
  25. >Anyways, I have to write a program for a class, all it needs to
  26. >do is multiply two matrices together, but I decided to brush up
  27. >on my C++ and to forgoe using ada or pascal to  just throw some-
  28. >thing together. 
  29.  
  30. >Bellow is the program I wrote.  It implements a class called 
  31. >Matrix, which allocates memory on the heap for the storage of
  32. >a matrix of XxY dimensions.  It also implements a copy constructor
  33. >for assignment, and a couple of different mathematical operations
  34. >to be performed on the matrix.
  35.  
  36. >I've got one big problem, and one little one, even though this
  37. >does compile and run fine the way it is (I'm compiling this as
  38. >a Visual C++ 4.0 Console Application).
  39.  
  40. >The first problem involves this very peculiar inconsistency that
  41. >I can't explain, for instance, this works:
  42.  
  43. >          Matrix M3 = Matrix1 * Matrix2;
  44.  
  45. >whereas defining Matrix M3 ahead of time
  46.  
  47. >          M3 = Matrix1 * Matrix2;
  48.  
  49. >crashes out on me giving me an error.  I can't really tell why.
  50. >It's a memory allocation assertion error.  I can't figure out
  51. >why I can't do the second method.  I was thinking about this, 
  52. >and I have another question related to this.  When I define
  53. >the Matrix M3 and assign it right away, is the Default Blank
  54. >Constructor called, THEN the Copy Constructor?  Or just the
  55. >copy constructor?  Also, say the copy Constructor was called.
  56. >When the new data is copied over, is the Destructor called 
  57. >before the copy constructor is used to copy the new data over?
  58. >I think these questions could definately shed some light as to
  59. >the inconsistency noted above.
  60.  
  61. Well I looked into this just yesterday and I found the following.
  62.  
  63. Matric M3 = Matrix1 * Matrix2;
  64.  
  65. is (just about) identical to
  66.  
  67. Matrix M3 (Matrix1 * Matrix2);
  68.  
  69. The only possiable difference is that there might be an extra temp
  70. variable created in the first case but most good compilers shouldn't.
  71.  
  72. >Also, my second problem is pretty simple.  It relates to using
  73. >variable arguments.  Is there anything peculiar or different
  74. >about Visual C++'s variable arguments?  I was trying to initialize
  75. >the Matrices by using variable arguments, rather than passing
  76. >a pointer to an array of Integers, but I could not get the
  77. >constructor to get the proper numbers.  I was basing the code
  78. >EXACTLY like what was in my C++ for Pascal Programmers book, 
  79. >nearly statement by statement, but it didn't work.  Visual C++
  80. >accepted the syntax, and everything looked ok, but I was just
  81. >not getting the right values.
  82.  
  83. >Here is the CPP file.  It's one file and can be copied.  I even
  84. >commented out this text so you can just save the message to
  85. >a file and copy it directly if you would like to take a look at 
  86. >it.
  87.  
  88. >Any help would be GREATLY appreciated!
  89. >*/
  90.  
  91. >/******************************************************************
  92. >  
  93. >  Author:   Bryan Murphy
  94. >  Class:    CPS 341
  95. >  Teacher:    Y. Pan
  96. >  Due Date: Monday 3/4/96
  97.  
  98. >  This program implements a Matrix class and the appropriate
  99. >  Multiplication and Division functions for that class.  The
  100. >  program then demonstrates the use of this class.
  101.  
  102. >******************************************************************/
  103. >#include "iostream.h"
  104. >#include "stdarg.h"
  105. >#include "stdlib.h"
  106.  
  107. >class Matrix {
  108. >public:
  109. >    Matrix();                        // Constructor
  110. >    Matrix(int,int,int const *);    // Constructor
  111. >    ~Matrix();                        // Destructor
  112.  
  113. >    Matrix(const Matrix &);            // Copy Constructor
  114.  
  115. >    int GetData(int,int);            // Get Number from Matrix
  116. >    void SetData(int,int,int);        // Set a Value in the Matrix
  117. >    void Display(void);                // Display Contents of Matrix
  118.  
  119. >    int Xdim()    { return xdim+1; }  // In case the size needs
  120. >    int Ydim()  { return ydim+1; }  // to be checked.
  121.  
  122. Missing operator = This will be a big problem if the compiler is
  123. generating one for you!
  124.     Matrix& operator = (const Matrix& rhs)
  125.     {
  126.     ~Matrix();        // Big hack, but I'm not going to write your code :-)
  127.     Matrix (rhs);    // Should work, just isn't nice
  128.     return *this;
  129.     }
  130.  
  131. >    // The following are the operations that can be
  132. >    // performed on a matrix.
  133. >    friend Matrix operator * (Matrix, Matrix);    // Matrix *
  134. >    friend Matrix operator * (Matrix, int);        // Scalar *
  135. >    friend Matrix operator + (Matrix, Matrix);    // Matrix +
  136. >    friend Matrix operator - (Matrix, Matrix);    // Matrix -
  137. >        
  138. >private:
  139.  
  140. >    int    xdim;                        // X size of Matrix
  141. >    int    ydim;                        // Y size of Matrix
  142.  
  143. >    int    *MatrixData;                // Contents of Matrix
  144. >};
  145.  
  146.  
  147. >// Matrix Constructor.  This constructor initializes the
  148. >// matrix and allocates memory for the matrix data.
  149. >Matrix::Matrix(int x, int y, int const *data = 0)
  150. >{
  151. >    // Set matrix size (numbering system 0 to X-1)
  152. >    xdim = (x-1);
  153. >    ydim = (y-1);
  154.  
  155. >    // Allocate memory for matrix
  156. >    MatrixData = new int[x*y];
  157.  
  158. >    // Check for memory allocation error
  159. >    if (MatrixData == 0) throw "Memory Allocation Error";
  160.  
  161. >    // Copy Data to Matrix if Available
  162. >    if (data !=0) 
  163. >        for (int i=0; i<x*y; i++) MatrixData[i] = data[i];
  164. >    else
  165. >        for (int i=0; i<x*y; i++) MatrixData[i] = 0;
  166.  
  167. >}
  168.  
  169. >// This constructor is for special cases where we don't
  170. >// know what the resulting member will look like.
  171. >Matrix::Matrix()
  172. >{
  173. >    xdim = 0;
  174. >    ydim = 0;
  175. >    MatrixData = 0;
  176. >}
  177.  
  178. >// Matrix Destructor.  Clean up the mess.
  179. >Matrix::~Matrix()
  180. >{
  181. >    // Free up the memory used
  182. >    delete MatrixData;
  183. >}
  184.  
  185. >// This is used for copying and assignment (ie. Matrx = Matrx2;)
  186. >Matrix::Matrix(const Matrix &Mat)
  187. >{
  188. >    int size = (Mat.xdim+1)*(Mat.ydim+1);
  189. >    MatrixData = new int[size];
  190.  
  191. >    xdim = Mat.xdim;
  192. >    ydim = Mat.ydim;
  193.  
  194. >    // Copy the Data over
  195. >    for (int i=0; i<size; i++) MatrixData[i] = Mat.MatrixData[i];
  196. >    
  197. >}
  198.  
  199. >// This function is used to get a specific value from a 
  200. >// matrix in position (x,y)
  201. >int Matrix::GetData(int x,int y)
  202. >{
  203. >    // Convert to matrix indices
  204. >    x--; 
  205. >    y--;
  206.  
  207. >    // Make sure X and Y are within bounds
  208. >    if (x<0 || x>xdim) throw("X out of Matrix Bounds");
  209. >    if (y<0 || y>ydim) throw("Y out of Matrix Bounds");
  210. >    
  211. >    // Return Value if no Exceptions Raised
  212. >    return MatrixData[y+x*(ydim+1)];    
  213. >}
  214.  
  215. >// Set a value in a Matrix
  216. >void Matrix::SetData(int x,int y,int value)
  217. >{
  218. >    // Convert to matrix indices
  219. >    x--; 
  220. >    y--;
  221.  
  222. >    // Make sure X and Y are within bounds
  223. >    if (x<0 || x>xdim) throw("X out of Matrix Bounds");
  224. >    if (y<0 || y>ydim) throw("Y out of Matrix Bounds");
  225.  
  226. >    MatrixData[y+x*(ydim+1)] = value;
  227. >}
  228.  
  229. >// Display the Contents of the Matrix
  230. >void Matrix::Display(void)
  231. >{
  232. >    // Just in Case...
  233. >    if (MatrixData == 0) throw("Internal Matrix Error!");
  234.  
  235. >    cout << xdim+1 << "x" << ydim+1 << " Matrix" << endl;
  236.  
  237. >    // Display Matrix
  238. >    for (int x=0; x<=xdim; x++)
  239. >    {
  240. >        for (int y=0; y<=ydim; y++)
  241. >        {
  242. >            // For Formatting Purposes
  243. >            if (MatrixData[y+x*(ydim+1)] < 10)
  244. >                cout << " ";
  245.  
  246. >            cout << " " << MatrixData[y+x*(ydim+1)];
  247. >        }
  248. >        cout << endl;
  249. >    }
  250. >}
  251.  
  252.  
  253. >// * operator for Matrices
  254. >Matrix operator * (Matrix M1, Matrix M2)
  255. >{
  256. >    // M1 columns must equal M2 rows
  257. >    if (M1.ydim != M2.xdim)
  258. >        throw "Matrices cannnot be multiplied!";
  259.  
  260. >    Matrix M3(M1.xdim+1,M2.ydim+1);
  261.  
  262. >    // Do the Multiplication
  263. >    for (int i=1; i<M1.Xdim(); i++)
  264. >        for (int j=1; j<M2.Ydim(); j++)
  265. >        {
  266. >            M3.SetData(i,j,0);
  267. >            for (int k=1; k<M2.Xdim(); k++)
  268. >                M3.SetData(i,j,M3.GetData(i,j)+
  269. >                               M1.GetData(i,k)*M2.GetData(k,j));
  270. >        }
  271.  
  272. >    return M3;
  273. >}
  274.  
  275. >// This is for multiplication by a Scalar
  276. >Matrix operator * (Matrix M1, int Scalar)
  277. >{
  278. >    Matrix Temp(M1.xdim+1,M1.ydim+1);
  279. >    int size = (M1.xdim+1)*(M1.ydim+1);
  280.  
  281. >    // Multiply matrix by scalar
  282. >    for (int i=0; i<size; i++) 
  283. >        Temp.MatrixData[i] = M1.MatrixData[i] * Scalar;
  284.  
  285. >    return Temp;
  286. >}
  287.  
  288. >// Add two Matrices together
  289. >Matrix operator + (Matrix M1, Matrix M2)
  290. >{
  291. >    // Matrices must be same dimensions
  292. >    if ((M1.xdim != M2.xdim)||(M1.ydim != M2.ydim))
  293. >        throw "Matrices cannot be added!";
  294.  
  295. >    Matrix Temp(M1.xdim+1,M1.ydim+1);
  296. >    int size = (M1.xdim+1)*(M1.ydim+1);
  297.  
  298. >    // Do the addition
  299. >    for (int i=0; i<size; i++)
  300. >        Temp.MatrixData[i] = M1.MatrixData[i] + M2.MatrixData[i];
  301.  
  302. >    return Temp;
  303. >}
  304.  
  305. >// Subtract two Matrices
  306. >Matrix operator - (Matrix M1, Matrix M2)
  307. >{
  308. >    // Matrices must be same dimensions
  309. >    if ((M1.xdim != M2.xdim)||(M1.ydim != M2.ydim))
  310. >        throw "Matrices cannot be subtracted!";
  311.  
  312. >    Matrix Temp(M1.xdim+1,M1.ydim+1);
  313. >    int size = (M1.xdim+1)*(M1.ydim+1);
  314.  
  315. >    // Do the Subtraction
  316. >    for (int i=0; i<size; i++)
  317. >        Temp.MatrixData[i] = M1.MatrixData[i] - M2.MatrixData[i];
  318.  
  319. >    return Temp;
  320. >}
  321.  
  322. >// Define matrix data as arrays
  323. >int        Mat4x4a[16] = {1, 2, 3, 4,
  324. >                       5, 6, 7, 8,
  325. >                       9, 10,11,12,
  326. >                       13,14,15,16};
  327.  
  328. >int        Mat4x4b[16] = {0, 1, 1, 1,
  329. >                        1, 0, 1, 1,
  330. >                       1, 1, 0, 1,
  331. >                       1, 1, 1, 0};
  332.  
  333. >main() 
  334. >{
  335. >    // Define Two Matrix Variables
  336. >    Matrix M1(4,4, Mat4x4a);
  337. >    Matrix M2(4,4, Mat4x4b);
  338.  
  339. >    // Test Matrix Operations
  340. >    Matrix M3 = M1 * M2;
  341. >    Matrix M4 = M2 * M1;
  342. >    Matrix M5 = M1 + M2;
  343.  
  344. >    // Print out the Results
  345. >    cout << "Matrix A:"   << endl; M1.Display();
  346. >    cout << "Matrix B:"   << endl; M2.Display();
  347. >    cout << "Matrix A*B:" << endl; M3.Display();
  348. >    cout << "Matrix B*A:" << endl; M4.Display();
  349. >    cout << "Matrix A+B:" << endl; M5.Display();
  350.  
  351. >    return 0;
  352. >}
  353. >-- 
  354.  
  355.  
  356.